import 'package:ideology/shared/widgets/code_input/config/editor_metrics.dart';

/// 编辑器的全局配置参数集合。
///
/// 该配置类用于集中管理文本编辑器的行为参数和视觉度量，
/// 包括 Tab 显示宽度、多击判定逻辑、自动滚动策略、光标闪烁周期等。
///
/// 特点：
/// - 默认参数适配一般代码编辑场景；
/// - 支持通过 [copyWith] 创建定制化副本；
/// - 保留了旧版像素级自动滚动速度参数以兼容历史代码。
class EditorConfig {
  /// Tab 转为空格时的宽度。
  ///
  /// 默认 `4`。
  final int tabSpaces;

  /// 多击判定的时间窗口。
  ///
  /// 若在该时间内连续点击，则可识别为双击/三击。
  ///
  /// 默认 `300ms`。
  final Duration multiClickTimeout;

  /// 多击判定的空间容差（px）。
  ///
  /// 鼠标点击位置若在该范围内仍视为连续点击。
  ///
  /// 默认 `6.0`。
  final double multiClickSlop;

  // ========= 自动滚动 =========

  /// 自动滚动触发边缘区域的宽度（px）。
  ///
  /// 鼠标/光标靠近边缘时进入该区域触发滚动。
  ///
  /// 默认 `48.0`。
  final double autoScrollMargin;

  /// 自动滚动死区（px）。
  ///
  /// 在 [autoScrollMargin] 内但未超过该距离时不触发滚动，避免误触。
  ///
  /// 默认 `8.0`。
  final double autoScrollDeadZone;

  /// 自动滚动的最小速度（行/秒）。
  ///
  /// 进入触发区域的最浅位置时的滚动速度。
  ///
  /// 默认 `10.0`。
  final double autoScrollMinLinesPerSec;

  /// 自动滚动的最大速度（行/秒）。
  ///
  /// 鼠标/光标紧贴边缘时的滚动速度。
  ///
  /// 默认 `80.0`。
  final double autoScrollMaxLinesPerSec;

  /// 自动滚动速度曲线的指数。
  ///
  /// - `1.0` 表示线性；
  /// - 大于 `1.0` 时曲线更加柔和。
  ///
  /// 默认 `2.2`。
  final double autoScrollExponent;

  /// 自动滚动的定时器 tick 间隔。
  ///
  /// 默认 `16ms`，约等于 60fps。
  final Duration autoScrollTick;

  /// （兼容旧版）像素级最大滚动速度。
  ///
  /// 单位：px/s。优先级低于 [autoScrollMinLinesPerSec]/[autoScrollMaxLinesPerSec]。
  ///
  /// 默认 `900.0`。
  final double autoScrollMaxSpeed;

  // ========= 光标 / 样式 =========

  /// 光标闪烁的周期。
  ///
  /// 默认 `500ms`。
  final Duration caretBlinkPeriod;

  /// 编辑器度量和样式配置。
  ///
  /// 包含字体样式、行高、字宽等。
  final EditorMetrics metrics;

  /// 构造一个 [EditorConfig]。
  ///
  /// 所有参数都有合理默认值，可按需覆盖。
  const EditorConfig({
    this.tabSpaces = 4,
    this.multiClickTimeout = const Duration(milliseconds: 300),
    this.multiClickSlop = 6.0,

    // 自动滚动
    this.autoScrollMargin = 48.0,
    this.autoScrollDeadZone = 8.0,
    this.autoScrollMinLinesPerSec = 10.0,
    this.autoScrollMaxLinesPerSec = 80.0,
    this.autoScrollExponent = 2.2,
    this.autoScrollTick = const Duration(milliseconds: 16),

    // 兼容旧字段
    this.autoScrollMaxSpeed = 900.0,

    this.caretBlinkPeriod = const Duration(milliseconds: 500),
    this.metrics = const EditorMetrics(),
  });

  /// 创建一个新的 [EditorConfig] 副本。
  ///
  /// 仅覆盖传入的字段，其余保持原值。
  EditorConfig copyWith({
    int? tabSpaces,
    Duration? multiClickTimeout,
    double? multiClickSlop,
    double? autoScrollMargin,
    double? autoScrollDeadZone,
    double? autoScrollMinLinesPerSec,
    double? autoScrollMaxLinesPerSec,
    double? autoScrollExponent,
    Duration? autoScrollTick,
    double? autoScrollMaxSpeed,
    Duration? caretBlinkPeriod,
    EditorMetrics? metrics,
  }) {
    return EditorConfig(
      tabSpaces: tabSpaces ?? this.tabSpaces,
      multiClickTimeout: multiClickTimeout ?? this.multiClickTimeout,
      multiClickSlop: multiClickSlop ?? this.multiClickSlop,
      autoScrollMargin: autoScrollMargin ?? this.autoScrollMargin,
      autoScrollDeadZone: autoScrollDeadZone ?? this.autoScrollDeadZone,
      autoScrollMinLinesPerSec:
      autoScrollMinLinesPerSec ?? this.autoScrollMinLinesPerSec,
      autoScrollMaxLinesPerSec:
      autoScrollMaxLinesPerSec ?? this.autoScrollMaxLinesPerSec,
      autoScrollExponent: autoScrollExponent ?? this.autoScrollExponent,
      autoScrollTick: autoScrollTick ?? this.autoScrollTick,
      autoScrollMaxSpeed: autoScrollMaxSpeed ?? this.autoScrollMaxSpeed,
      caretBlinkPeriod: caretBlinkPeriod ?? this.caretBlinkPeriod,
      metrics: metrics ?? this.metrics,
    );
  }
}
